package scheduler

import (
	"encoding/json"
	apis2 "gluenet/pkg/apis"
	"gluenet/pkg/meta"
	"net/http"
)

const listAllAgents = "select * from agent_status where status = \"Ready\""

func schedule(c apis2.GlueContext) {
	var (
		err      error
		instance *meta.Instance
	)

	c.Logger.Debugf("receive schedule event")

	// 解码数据
	if instance, err = decodeSchduleEvent(c.RpcContext.Data.Data); err != nil {
		c.Logger.Errorf("%v", err)
		return
	}

	// 查询agent
	var agents []meta.Agent
	if err = c.DataBase.AgentListAll(&agents); err != nil {
		c.Logger.Errorf("%v", err)
		return
	}

	var scheduleRes *meta.ScheduleResults
	if scheduleRes, err = scheduleOne(agents, instance); err != nil {
		c.Logger.Errorf("%v", err)
		return
	}

	c.Logger.Debugf("schedule result %v", scheduleRes)

	bts, _ := json.Marshal(instance)
	//启动agent
	data := [3]interface{}{scheduleRes, string(bts), apis2.OpInstanceCreate}
	publishOk(&c, data)

	//存储数据
	c.DataBase.ScheduleResultPut(scheduleRes)
	//orm2.SaveScheduleResult(&c, scheduleRes)
}

func unschedule(c apis2.GlueContext) {
	var (
		err            error
		ins            *meta.Instance
		scheduleResult *meta.ScheduleResults
	)

	c.Logger.Debugf("receive schedule event")
	//c.Logger.Debugf("receive schedule event %s", c.RpcContext.Data.Data)

	// 解码数据
	if ins, err = decodeSchduleEvent(c.RpcContext.Data.Data); err != nil {
		c.Logger.Errorf("%v", err)
		return
	}

	// 查询调度结果
	if err = c.DataBase.ScheduleResultGet(ins.Guid, &scheduleResult); err != nil {
		c.Logger.Errorf("%v", err)
		return
	}

	bts, _ := json.Marshal(ins)

	// 发布撤销命令
	data := [3]interface{}{scheduleResult, string(bts), apis2.OpInstanceDelete}
	publishOk(&c, data)

	// 删除调度结果
	if err = c.DataBase.ScheduleResultDel(ins.Guid); err != nil {
		c.Logger.Errorf("%v", err)
		return
	}
}

func decodeSchduleEvent(data []byte) (*meta.Instance, error) {
	var req = apis2.IEvent{}
	if err := json.Unmarshal(data, &req); err != nil {
		return nil, err
	}
	bts, _ := json.Marshal(req.Data)
	var ins = meta.Instance{}
	if err := json.Unmarshal(bts, &ins); err != nil {
		return nil, err
	}
	return &ins, nil
}

func publishOk(c *apis2.GlueContext, data interface{}) {
	resp := apis2.IEvent{
		Code:    http.StatusOK,
		Message: "succeed",
		Data:    data,
	}
	bts, _ := json.Marshal(resp)
	if err := c.Rpc.Publish(apis2.SchedulerEventResult, bts); err != nil {
		c.Logger.Errorf("push schedule result %v", err)
	}
}
